home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / listings / v_12_03 / olsen / pars.c < prev    next >
C/C++ Source or Header  |  1994-02-07  |  8KB  |  305 lines

  1. /* LISTING 2 */
  2. /* pars.c */
  3. /* no copyrights claimed */
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <ctype.h>
  7. #include <string.h>
  8. #include "parsdef.h"
  9.  
  10. static toDoList toDo[MAX_STATEMENTS];
  11. static char stringPool[STRINGPOOL];
  12. static char *pPool, *poolEnd;
  13. static char message[MESSAGELENGTH];
  14. static char *messList[]= {
  15.     "EMPTY","error","empty","assign","request",
  16.     "to_eeprom","is","command","integer","float",
  17.     "name","name_error","op_error","val_error",
  18.     "end_error","pool_error"
  19. };
  20.  
  21. main()
  22. {
  23.     while(1) {
  24.         pPool= stringPool;
  25.         poolEnd= stringPool+STRINGPOOL-1;
  26.         printf("\nmessage: ");
  27.         gets(message);
  28.         if(message[0]=='.') break;
  29.         Parse(message, toDo);
  30.         PrintToDo(toDo);
  31.         DoCommands(toDo);
  32.     }
  33. }
  34.  
  35. /* first, the parsing */
  36.  
  37. void Parse(char *message, toDoList *pToDo)
  38. {
  39.     char *pC, token[MAX_TOKEN_LEN+1];
  40.     int type, i;
  41.     pC= message;
  42.     for(i=0; i<MAX_STATEMENTS; i++) {
  43.         (pToDo+1)->command= EMPTY; /* mark end */
  44.         if(*pC=='\0'){pToDo->command= EMPTY; return;}
  45.         /* get name */
  46.         pC= GetNextToken(pC, token, &type);
  47.         if(StoreToken(&pToDo->name, token) != 0)
  48.             { pToDo->command=POOL_ERROR; return; }
  49.         if((type==ERROR)||(type!=NAME))
  50.             { pToDo->command= NAME_ERROR; return; }
  51.         if(*pC=='\0') {pToDo->command=EMPTY; return;}
  52.         /* get operator */
  53.         pC= GetNextToken(pC, token, &type);
  54.         if(type==ERROR)
  55.             {pToDo->command=OP_ERROR; return;}
  56.         pToDo->command= type;
  57.         /* get value */
  58.         if((type==ASSIGN)||(type==TO_EEPROM)||
  59.             (type==IS)) {
  60.             if(*pC=='\0')
  61.                 {pToDo->command=VAL_ERROR; return;}
  62.             pC= GetNextToken(pC, token, &type);
  63.             pToDo->type= type;
  64.             if(type==INTEGER)
  65.                 pToDo->value= atoi(token);
  66.             else {pToDo->command= VAL_ERROR; return;}
  67.         }
  68.         else pToDo->type= INTEGER;
  69.         if(pToDo->command== EMPTY) return;
  70.         pToDo++;
  71.     }
  72.     pToDo->command= END_ERROR;
  73.     return;
  74. }
  75.  
  76. char *GetNextToken(char *begin, char *token, int *type)
  77. {
  78.     char *pC, *pT;
  79.     int i;
  80.     pC= begin;
  81.     pT= token;
  82.     *token= '\0';
  83.     *type= EMPTY;
  84.     if(*pC == '\0') {return pC;}
  85.     /* remove leading spaces */
  86.     while(*pC==' ') pC++;
  87.     if(*pC=='\0') return pC;
  88.     if(isalpha(*pC)) { /* name */
  89.         *type= NAME;
  90.         *pT++= *pC++;
  91.         for(i=1; i<MAX_TOKEN_LEN; i++) {
  92.             if((isalpha(*pC)) || (isdigit(*pC))
  93.                 || (*pC=='_')) *pT++= *pC++;
  94.             else {
  95.                 *pT= '\0';
  96.                 return pC;
  97.             }
  98.         }
  99.     *type= ERROR;
  100.     return pC;
  101.     }
  102.     else if((isdigit(*pC))||(*pC=='+')||
  103.         (*pC=='-')) { /* number */
  104.         *pT++= *pC++;
  105.         for(i=1; i<MAX_TOKEN_LEN; i++) {
  106.             if(isdigit(*pC)) *pT++= *pC++;
  107.             else {
  108.                 *pT= '\0';
  109.                 *type= INTEGER;
  110.                 return pC;
  111.             }
  112.         }
  113.         *type= ERROR;
  114.         return pC;
  115.     }
  116.     else if(*pC== '=') *type= ASSIGN;
  117.     else if(*pC== '?') *type= REQUEST;
  118.     else if(*pC== '>') *type= TO_EEPROM;
  119.     else if(*pC== ':') *type= IS;
  120.     else if(*pC== '!') *type= COMMAND;
  121.     else {*type= ERROR; return ++pC;}
  122.     return ++pC;
  123. }
  124.  
  125. int StoreToken(char **ppName, char *token)
  126. {
  127.     int length;
  128.     *ppName= pPool;
  129.     length= strlen(token)+1;
  130.     if((pPool+length)>=poolEnd) return -1;
  131.     strcpy(pPool, token);
  132.     pPool+= length;
  133.     return 0;
  134. }
  135.  
  136. /* and now, the action */
  137.  
  138. static symTabEntry symTab[]= {
  139.     {"reset"  , 0     , Reset, -1},
  140.     {"status" , 35    , NULL , -1},
  141.     {"temp"   , 16    , NULL , 20}
  142. };
  143.  
  144. void PrintToDo(toDoList *toDo)
  145. {
  146.     while(toDo->command != EMPTY) {
  147.         printf("\n %s %s '%s'",
  148.             messList[toDo->command],
  149.             messList[toDo->type], toDo->name);
  150.         if(toDo->type==INTEGER)
  151.             printf(" %d", toDo->value);
  152.         toDo++;
  153.     }
  154. }
  155.  
  156.  
  157. int SymCmp(symTabEntry *a, symTabEntry *b)
  158. {
  159.     return strcmp(a->name, b->name);
  160. }
  161.  
  162. symTabEntry *FindSymbol(char *pName)
  163. {
  164.     symTabEntry dummy, *p;
  165.     dummy.name= pName;
  166.     p= (symTabEntry*) bsearch(&dummy, symTab,
  167.         sizeof(symTab)/sizeof(symTabEntry),
  168.         sizeof(symTabEntry),
  169.         (int(*)(const void*, const void*))SymCmp);
  170.     return p;
  171. }
  172.  
  173. char *Reset(char *pC)
  174. {
  175.     printf("\nExecuting 'Reset'");
  176.     return pC;
  177. }
  178.  
  179. void DoCommands(toDoList *pToDo)
  180. {
  181.     char *txBuffer, *pTx;
  182.     txBuffer= pTx= TxBuffer();
  183.     *pTx= '\0';
  184.     while(pToDo->command != EMPTY) {
  185.     switch(pToDo->command) {
  186.     case ERROR:
  187.     case NAME_ERROR:
  188.     case OP_ERROR:
  189.     case VAL_ERROR:
  190.     case END_ERROR:
  191.     case POOL_ERROR:
  192.         pTx= SayError(pToDo, pToDo->command, pTx);
  193.         break;
  194.         case ASSIGN:    pTx= Assign(pToDo, pTx);
  195.                         break;
  196.         case REQUEST:   pTx= Request(pToDo, pTx);
  197.                         break;
  198.         case TO_EEPROM: pTx= ToEeprom(pToDo, pTx);
  199.                         break;
  200.         case COMMAND:   pTx= RunCommand(pToDo, pTx);
  201.                         break;
  202.         default:        break;
  203.     }
  204.     ++pToDo;
  205.     }
  206.     printf("\ntxBuffer: '%s'\n", txBuffer);
  207. }
  208.  
  209. char *SayError(toDoList *pToDo, int err, char *pC)
  210. {
  211.     char str[MAX_TOKEN_LEN+1], *pS;
  212.     pS= pToDo->name;
  213.     while(*pC++=*pS++);
  214.     pC--;
  215.     *pC++= '#';
  216.     sprintf(str,"%-d", err);
  217.     pS= str;
  218.     while(*pC++= *pS++);
  219.     return --pC;
  220. }
  221.  
  222. char *Assign(toDoList *pToDo, char *pTx)
  223. {
  224.     symTabEntry *pSym;
  225.     pSym= FindSymbol(pToDo->name);
  226.     if(pSym==NULL) {
  227.         pTx= SayError(pToDo, UNDEF_SYMB, pTx);
  228.         return pTx;
  229.     }
  230.     if(pToDo->type==INTEGER) pSym->ival= pToDo->value;
  231.     if(pSym->func!=NULL) pTx= (*pSym->func)(pTx);
  232.     return pTx;
  233. }
  234.  
  235. char *Request(toDoList *pToDo, char *pTx)
  236. {
  237.     symTabEntry *pSym;
  238.     char *pS, str[MAX_TOKEN_LEN+1];
  239.     pSym= FindSymbol(pToDo->name);
  240.     if(pSym==NULL) {
  241.         pTx= SayError(pToDo, UNDEF_SYMB, pTx);
  242.         return pTx;
  243.     }
  244.     pS= pToDo->name;
  245.     while(*pTx++=*pS++);
  246.     pTx--;
  247.     *pTx++= '=';
  248.     if(pToDo->type==INTEGER)
  249.         sprintf(str,"%-d", pSym->ival);
  250.     pS= str;
  251.     while(*pTx++=*pS++);
  252.     if(pSym->func!=NULL) pTx= (*pSym->func)(pTx);
  253.     return --pTx;
  254. }
  255.  
  256. char *ToEeprom(toDoList *pToDo, char *pTx)
  257. {
  258.     symTabEntry *pSym;
  259.     pSym= FindSymbol(pToDo->name);
  260.     if(pSym==NULL) {
  261.         pTx= SayError(pToDo, UNDEF_SYMB, pTx);
  262.         return pTx;
  263.     }
  264.     if(pSym->eeOffset<0) {
  265.         pTx= SayError(pToDo, NOT_EEPROM, pTx);
  266.         return pTx;
  267.     }
  268.     if(pToDo->type==INTEGER) {
  269.         pSym->ival= pToDo->value;
  270.         WriteEeprom(pSym, INTEGER);
  271.     }
  272.     if(pSym->func!=NULL) pTx= (*pSym->func)(pTx);
  273.     return pTx;
  274.     }
  275.  
  276. char *RunCommand(toDoList *pToDo, char *pTx)
  277. {
  278.     symTabEntry *pSym;
  279.     pSym= FindSymbol(pToDo->name);
  280.     if(pSym==NULL) {
  281.         pTx= SayError(pToDo, UNDEF_SYMB, pTx);
  282.         return pTx;
  283.     }
  284.     if(pSym->func!=NULL) pTx= (*pSym->func)(pTx);
  285.     else {
  286.         pTx=SayError(pToDo, UNDEF_FUNC, pTx);
  287.         return pTx;
  288.     }
  289.     return pTx;
  290. }
  291.  
  292. char *TxBuffer(void)
  293. {
  294.     static char buffer[200];
  295.     return buffer;
  296. }
  297.  
  298. void WriteEeprom(symTabEntry *pSym, int type)
  299. {
  300.     if(type==INTEGER) printf(
  301.         "\nTo EE, type: %d off: %d val: %d\n",
  302.         type, pSym->eeOffset, pSym->ival);
  303.     return;
  304. }
  305.